/*
 * Copyright (c) 2025 Industrial Software Feature Database
 */
package com.comac.ins.isfd.util.bdfparser.parsers;

import cn.hutool.core.collection.CollectionUtil;
import com.comac.ins.common.core.utils.StringUtils;
import com.comac.ins.isfd.util.bdfparser.entities.bdf.cards.BaseCard;
import com.comac.ins.isfd.util.bdfparser.entities.bdf.cards.Comment;
import com.comac.ins.isfd.util.bdfparser.entities.bdf.rawdata.RawDataLine;
import com.comac.ins.isfd.util.bdfparser.entities.bdf.sections.BulkDataEntry;
import com.comac.ins.isfd.util.bdfparser.enums.ContentTypeEnum;
import com.comac.ins.isfd.util.bdfparser.enums.cardeums.CardNameEnums;
import com.comac.ins.isfd.util.bdfparser.enums.cardeums.CardTypeEnums;
import com.comac.ins.isfd.util.bdfparser.validation.CardValidationUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.CollectionUtils;

import java.util.*;

/**
 * 卡片通用的一些方法类
 */
@Slf4j
public class BasicCardUtils {

    /**
     * 解析原始数据行为卡片数据
     */
    public static void parseCards(BulkDataEntry bulkDataEntry, List<RawDataLine> rawDataLines) {
        log.info("解析卡片数据");
        if (CollectionUtil.isEmpty(rawDataLines)) {
            log.warn("BULK DATA ENTRY 为空");
        }
        //  初始化一些bulk data entry 参数
        List<Comment> comments = new ArrayList<>();
        Map<String, Integer> cardCount = new HashMap<>();
        List<BaseCard> cardList= new ArrayList<>();
        Map<String, Integer> rejectedCardCount= new HashMap<>();
        List<BaseCard> rejectedCardList= new ArrayList<>();
        // 初始化一些解析参数
        String previousCardName = "";
        List<RawDataLine> cardLines = new ArrayList<>();
        List<String> inlineComments = new ArrayList<>();
        Comment comment = new Comment();
        boolean isHyperMeshCard = false; // HyperMesh 卡片解析
        for (int i = 0; i < rawDataLines.size(); i++) {
            RawDataLine rawDataLine = rawDataLines.get(i);
            String line = rawDataLine.getLine();
            // 处理头部'$'的情况
            if (line.startsWith("$")) {
                // 处理HyperMesh comment
                if (!isHyperMeshCard) {
                    if (line.startsWith("$HW") || line.startsWith("$HM")) {
                        isHyperMeshCard = true;
                    }
                    else {
                        // 剩余为注释
                        comment.getLines().add(rawDataLine);
                        continue;
                    }
                }
                else {
                    line = line.substring(1); // 是HyperMesh行
                }
            }
            // 处理inline comment
            if (!line.startsWith("$") && line.contains("$")) {
                String[] parts = line.split("\\$",2);
                line = parts[0]; // 数据部分
                String stripComment = parts.length > 1 ? parts[1].strip() : "";
                if (stripComment.toLowerCase().startsWith("group:")) {
                    // todo 是否需要处理
                }
                inlineComments.add(stripComment);
            }
            // 获取卡片名称
            String cardName = line.substring(0, Math.min(8, line.length())) // 截取前8个字符，防止越界
                .split(",", 2)[0]   // 按逗号分割，取第一部分
                .split("\t", 2)[0]  // 按制表符分割，取第一部分
                .strip()            // 去除两端空白
                .toUpperCase();     // 转为大写
            // 特殊处理HyperMesh卡片，
            if (isHyperMeshCard) {
                cardName = line.substring(0, Math.min(16, line.length()))
                    .split(" ")[0]             // 按空格截取，取第一部分
                    .split("\t", 2)[0]         // 按制表符截取，取第一部分
                    .replaceAll("[^A-Z_]", "") // 只保留大写字母和下划线
                    .strip()                   // 去除首尾空白
                    .toUpperCase();            // 转为大写
            }
            cardName = cardName.matches("^[A-Z][A-Z0-9_*]*$") ? cardName : "";
            // 记录下一张卡片前，处理上一张卡片
            if (StringUtils.isNotBlank(cardName) &&
                cardName.charAt(0) != '+' && cardName.charAt(0) != '*') {
                // 将卡片存储到卡片list
                BaseCard card = new BaseCard();
                card.setName(previousCardName);
                card.setComments(inlineComments);
                card.setRawDataLines(cardLines);
                // 保存 comment
                if (CollectionUtil.isNotEmpty(comment.getLines())) {
                    comments.add(comment);
                }
                // 验证并生成卡片, 插入卡片：有效或者废弃, 更新计数信息
                if (CardValidationUtils.isValidCard(card)) {
                    cardList.add(card); // 插入卡片
                    cardCount.merge(card.getName(), 1, Integer::sum);// 更新卡片计数
                } else {
                    rejectedCardList.add(card); // 废弃卡片
                    rejectedCardCount.merge(card.getName(), 1, Integer::sum); // 更新废弃卡片计数
                }
                // 初始化参数
                previousCardName = cardName.replaceAll("[ *]+$", "");
                cardLines = new ArrayList<>();
                inlineComments = new ArrayList<>();
                comment = new Comment();
                isHyperMeshCard = false;
                // 处理"END DATA"
                if (previousCardName.equals("ENDDATA")) {
                    cardCount.put(previousCardName, 1);
                    if (rawDataLines.size() - i > 1) {
                        log.warn("exiting due to ENDDATA, {} lines left", rawDataLines.size() - i);
                    }
                    return;
                }
            }
            // 未遇到下一张卡片，继续记录信息
            if (StringUtils.isNotBlank(rawDataLine.getLine())) {
                cardLines.add(rawDataLine);
            }
        }
        // 收尾
        if (CollectionUtil.isNotEmpty(cardLines)) {
            // 将卡片存储到卡片list
            BaseCard card = new BaseCard();
            card.setName(previousCardName);
            card.setComments(inlineComments);
            card.setRawDataLines(cardLines);
            // 验证并生成卡片，插入卡片：有效或者废弃, 更新计数信息
            if (CardValidationUtils.isValidCard(card)) {
                cardList.add(card); // 插入卡片
                cardCount.merge(card.getName(), 1, Integer::sum);// 更新卡片计数
            } else {
                rejectedCardList.add(card); // 废弃卡片
                rejectedCardCount.merge(card.getName(), 1, Integer::sum); // 更新废弃卡片计数
            }
        }
        // 保存解析信息
        bulkDataEntry.setCardList(cardList);
        bulkDataEntry.setRejectedCardList(rejectedCardList);
        bulkDataEntry.setCardCount(cardCount);
        bulkDataEntry.setRejectedCardCount(rejectedCardCount);
        bulkDataEntry.setComments(comments);
        // 去重校验
        //checkAndRemoveDuplicates(bulkDataEntry);
    }

    /**
     * 检查是否有重复卡片，并去重
     */
    public static void checkAndRemoveDuplicates(BulkDataEntry bulkDataEntry) {
        log.info("重复卡片检查");
        Map<String, BaseCard> cardIdMap = new HashMap<>();
        Iterator<BaseCard> iterator = bulkDataEntry.getCardList().iterator();
        while (iterator.hasNext()) {
            BaseCard card = iterator.next();
            // 生成唯一标识及type
            generateCardUniqueId(card);
            assert card.getUniqueId() != null;
            // 过滤掉不支持的卡片类型
            if (cardIdMap.containsKey(card.getUniqueId())) {
                iterator.remove();
                updateCardListsAndCounts(bulkDataEntry, card);
                continue;
            }
            cardIdMap.put(card.getUniqueId(), card);
        }
    }

    /**
     * 根据type生成唯一标识
     *
     */
    public static void generateCardUniqueId(BaseCard card) {
        // 获取卡片类型
        String cardType = CardTypeEnums.getCardTypeByName(card.getName());
        // 按照卡片类型生成唯一标识
        // todo: 完善分类
        if (cardType == null) {
            card.setUniqueId(card.getName() + card.getId());
            return;
        }
        else {
            card.setType(cardType);
            if (cardType.equals(CardTypeEnums.LOAD.getType())) {
                card.setUniqueId(
                    card.getName() + card.getId()
                        + card.getFields().get(0).get(2) + card.getFields().get(0).get(8)
                );
            }
            else {
                card.setUniqueId(card.getName() + card.getId());
            }
        }
    }

    /**
     * 更新卡片计数
     */
    private static void updateCardListsAndCounts(BulkDataEntry bulkDataEntry, BaseCard card) {
        bulkDataEntry.getCardCount().merge(card.getName(), -1, Integer::sum);// 更新卡片计数
        bulkDataEntry.getCardCount().remove(card.getName(), 0);
        bulkDataEntry.getRejectedCardCount().merge(card.getName(), 1, Integer::sum); // 更新废弃卡片计数
        bulkDataEntry.getRejectedCardList().add(card); // 添加到未解析列表
    }

}
